/* 
*  Copyright (C) 2009-2010 WCG Project
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/



/*
*	Admin Functions
*/


// This will handle every admin client command
public ADMIN_Handler( id )
{
	new szCmd[32]
	read_argv( 0, szCmd, 31 )


	// Make sure the user is an admin
	if ( !( get_user_flags( id ) & XP_GetAdminFlag() ) )
	{
		client_print( id, print_console, "%L", id, "YOU_HAVE_NO_ACCESS", g_MODclient )

		return PLUGIN_HANDLED
	}

	// OK we're free to go!!!


	new szArg1[32], szArg2[32]
	read_argv( 1, szArg1, 31 )
	read_argv( 2, szArg2, 31 )

	// Give the user XP
	if ( equal( szCmd, "wcg_givexp" ) )
	{
		if ( read_argc() < 3 )
		{
			ADMIN_Print( id, "Format: %s <name|#id|auth|@TEAM|@ALL> <xp>", szCmd )

			return PLUGIN_HANDLED
		}

		ADMIN_GiveXP( id, szArg1, str_to_num( szArg2 ) )
	}

	// Set the level of a user's race
	else if ( equal( szCmd, "wcg_setlevel" ) )
	{
		if ( read_argc() < 3 )
		{
			ADMIN_Print( id, "Format: %s <name|#id|auth|@TEAM|@ALL> <level>", szCmd )

			return PLUGIN_HANDLED
		}

		new iLevel = str_to_num( szArg2 )

		if ( iLevel < 0 || iLevel > MAX_LEVELS )
		{
			ADMIN_Print( id, "%s Error, level must be in between (or equal to) 0 and %d", g_MODclient, MAX_LEVELS )

			return PLUGIN_HANDLED
		}

		ADMIN_SetLevel( id, szArg1, iLevel )
	}

	// Give the user an item
	else if ( equal( szCmd, "wcg_giveitem" ) )
	{
		if ( read_argc() < 3 )
		{
			ADMIN_Print( id, "Format: %s <name|#id|auth|@TEAM|@ALL> <item id or name>", szCmd )

			return PLUGIN_HANDLED
		}

		new iItemID
		if ( is_str_num( szArg2 ) )
		{
			iItemID = str_to_num( szArg2 )
			if ( iItemID > 17 || iItemID < 0 )
			{
				ADMIN_Print( id, "%s Error, item id must be in between (or equal to) 0 and 17", g_MODclient )

				return PLUGIN_HANDLED
			}
		}

		ADMIN_GiveItem( id, szArg1, iItemID )
	}

	new szArgs[128]
	read_args( szArgs, 127 )

	ADMIN_Log( id, szCmd, "%s", szArgs )

	return PLUGIN_HANDLED
}


// Actually set the user's XP
ADMIN_SetXP( id, iXP )
{
	if ( iXP < 0 )
	{
		iXP = 0
	}

	PlayerInfo[id][PI_XP] = iXP

	XP_Check( id )

	set_task( 0.3, "WC3_GetUserInput", TASK_GETINPUT + id )
}

// Set the user's level
ADMIN_SetLevel( id, szTarget[], iLevel )
{

	new iXP = XP_GetByLevel( iLevel )

	new iTarget = 0, bool:bTargetFound = false

	// Do this while we continue having a target!
	while ( ( iTarget = FindTarget( iTarget, szTarget ) ) > 0 )
	{
		ADMIN_SetXP( iTarget, iXP )

		client_print( iTarget, print_chat, "%s The admin has set your race's level to %d", g_MODclient, iLevel )

		bTargetFound = true
	}
	
	// No target found :/
	if ( !bTargetFound )
	{
		ADMIN_NoTargetFound( id, szTarget, ( iTarget == -2 ) )
	}
}

// Give the user some XP
ADMIN_GiveXP( id, szTarget[], iXP )
{
	new iTarget = 0, bool:bTargetFound = false
	
	// Do this while we continue having a target!
	while ( ( iTarget = FindTarget( iTarget, szTarget ) ) > 0 )
	{
		ADMIN_SetXP( iTarget, PlayerInfo[iTarget][PI_XP] + iXP )

		client_print( iTarget, print_chat, "%s %L", g_MODclient, iTarget, "THE_ADMIN_GAVE_YOU_EXPERIENCE", iXP )

		bTargetFound = true
	}

	// No target found :/
	if ( !bTargetFound )
	{
		ADMIN_NoTargetFound( id, szTarget, ( iTarget == -2 ) )
	}
}

// Give the user an item
ADMIN_GiveItem( id, szTarget[], iItemID )
{
	new szItemName[32]
	LANG_GetItemName ( iItemID, id, szItemName, 31 )

	new iTarget = 0, bool:bTargetFound = false

	// Do this while we continue having a target!
	while ( ( iTarget = FindTarget( iTarget, szTarget ) ) > 0 )
	{
		client_print( iTarget, print_chat, "%s The admin has given you the item '%s'", g_MODclient, szItemName )
		
		ITEM_GiveItem( iTarget, iItemID )

		bTargetFound = true
	}

	// No target found :/
	if ( !bTargetFound )
	{
		ADMIN_NoTargetFound( id, szTarget, ( iTarget == -2 ) )
	}
}

// Find a user based on szTarget
FindTarget( iLastID, szTarget[] )
{
	
	new iTarget = -1

	// Then we want to basically return everyone!
	if ( equali( szTarget, "@ALL" ) )
	{
		new players[32], iTotalPlayers, i
		get_players( players, iTotalPlayers )
		
		// Loop through and search for the next target
		for ( i = 0; i < iTotalPlayers; i++ )
		{
			// Target found, so lets return the next one (if possible)!!
			if ( players[i] == iLastID && i + 1 != iTotalPlayers )
			{
				iTarget = players[i+1]
			}
		}

		// No target was found so return the first one
		if ( iTotalPlayers > 0 && iLastID == 0 )
		{
			iTarget = players[0]
		}
	}

	// Find a target based on the team
	else if ( szTarget[0] == '@' )
	{
		new iTeam = -1, id
		
		// Counter-Strike and Condition Zero Checks
		if ( equali( szTarget, "@T" ) )
			iTeam = TEAM_T
		else if ( equali( szTarget, "@CT" ) )
			iTeam = TEAM_CT
		

		// Make sure a team was found
		if ( iTeam != -1 )
		{
			new i, iFirstPlayer = -1, bool:bSaveNext = false

			// Loop through and search for the next target
			for( i = 0 ; i < g_NumTeamPlayers[iTeam] ; i++ )
			{
				id = g_SortedTeams[iTeam][i]

				// This is the next available player
				if( bSaveNext )
				{
					iTarget = id
					break
				}

				// If this is the previous target, we need to get the next one!
				if ( id == iLastID )
					bSaveNext = true
				
				// Save the FIRST player on this team
				if ( iFirstPlayer == -1 )
					iFirstPlayer = id
			}

			// No target was found so return the first one that matches the team (the target could still be -1 if iFirstPlayer wasn't found)
			if ( iLastID == 0 )
			{
				iTarget = iFirstPlayer
			}
		}
	}

	// Otherwise search for a player
	else
	{
		// Initial search is by player name
		new iPlayer = find_player( "a", szTarget )
		
		// If not found, search by partial match
		if ( !iPlayer )
		{
			iPlayer = find_player( "bl", szTarget )

			if ( iPlayer )
			{

				// Then Multiple clients found
				if ( iPlayer != find_player( "blj", szTarget ) )
				{
					return -2
				}
			}
		}

		// If not found, search by auth id
		if ( !iPlayer )
		{
			iPlayer = find_player( "c" , szTarget )
		}

		// If not found, search by user id
		if ( !iPlayer )
		{
			// Make sure we have a user id
			if ( szTarget[0] == '#' && szTarget[1] )
			{
				iPlayer = find_player( "k", str_to_num( szTarget[1] ) )
			}
		}
		
		// Yay we have a match!!!
		if ( iPlayer && iLastID != iPlayer )
		{
			iTarget = iPlayer
		}
	}

	return iTarget
}

ADMIN_NoTargetFound( id, szTarget[], bool:bMulti )
{
	// Multiple clients found
	if ( bMulti )
	{
		ADMIN_Print( id, "%s There is more than one client matching '%s'", g_MODclient, szTarget )
	}

	else
	{
		ADMIN_Print( id, "%s Unable to find target(s) '%s'", g_MODclient, szTarget )
	}

	// List what the available targets are
	ADMIN_Print( id, "%s Available targets are: @ALL, @CT, @T or the player's name/auth/#id", g_MODclient )
}

// Function will print to server console or client console based on the ID number
ADMIN_Print( id, text[], {Float,_}:...)
{    
	// format the text as needed

	new szFormattedText[128]
	format_args( szFormattedText, 127, 1 )

	if ( id == 0 )
	{
		server_print( szFormattedText )
	}
	else
	{
		client_print( id, print_console, szFormattedText )
	}

	// Gets rid of compiler warning
	if ( text[0] == 0 )
	{
		return
	}
}  

// Adapted from war3x's log file (I was lazy)
ADMIN_Log( id, szCommand[], {Float,_}:... )
{

	new szLogFile[128]
	get_configsdir( szLogFile, 127 )
	formatex( szLogFile, 127, "%s/wcg/wcg_admin.log", szLogFile )

	new szFormattedText[128]
	format_args( szFormattedText, 127, 2 )

	if ( !file_exists( szLogFile ) )
	{
		write_file( szLogFile, "Warcraft Generations", -1 )
		write_file( szLogFile, "Logging of admin commands", -1 )
		write_file( szLogFile, " ", -1 )
	}

	static szAdminName[32], szSteamID[32]
	if ( id > 0 )
	{
		get_user_name( id, szAdminName, 31 )
		get_user_authid( id, szSteamID, 31 )
	}
	else
	{
		copy( szAdminName, 31, "SERVER" )
		copy( szSteamID, 31, "SERVER" )
	}

	static szCurrentTime[32]
	get_time( "%m.%d.%Y %H:%M:%S", szCurrentTime, 31 )

	static szLogEntry[256]
	formatex( szLogEntry, 255, "[%s] %s (%s) used command: '%s %s'", szCurrentTime, szAdminName, szSteamID, szCommand, szFormattedText )

	write_file( szLogFile, szLogEntry, -1 )

	// Gets rid of compiler warning
	if ( szCommand[0] == 0 )
	{
		return
	}
}